package org.paraj.sync;

import java.util.concurrent.locks.Lock;

public interface ResourceMonitor{
    /**
     * Aquires resource described by <tt>key</tt> by creating corresponding write lock and calling its lock() method.
     * The lock is stored for later, so subsequent calls will use the same lock to aquire the resource.
     * Lock is stored in ResourceMonitor as weak reference, so when no longer needed it gets garbage collected.
     *
     * @param key - unique key for aquired resource. Object equality is taken into account unlike in synchronized(key){...}.
     *            It is responsibility of the caller to call unlock() on returned lock.
     *            example:
     *            <pre>
     *                 Lock lock = resourceMonitor.writerEnters(filename);
     *                 try{
     *                     CoreUtil.serializeToFile(filename, value );
     *                 }finally {
     *                     lock.unlock();
     *                 }
     *            </pre>
     * @return write lock corresponding to key
     * @see org.paraj.sync.ResourceMonitor#readerEnters
     */
    Lock writerEnters(Object key);

    /**
     * Aquires resource described by <tt>key</tt> by creating corresponding read lock and calling its lock() method.
     * The lock is stored for later, so subsequent calls will use the same lock to aquire the resource.
     * Lock is stored in ResourceMonitor as weak reference, so when no longer needed it gets garbage collected.
     *
     * @param key - unique key for aquired resource. Object equality is taken into account unlike in synchronized(key){...}
     *            It is responsibility of the caller to call unlock() on returned lock
     *            example:
     *            <pre>
     *                 Lock lock = resourceMonitor.readerEnters(filename);
     *                 try{
     *                     return CoreUtil.deserializeFromFile(filename) );
     *                 }finally {
     *                     lock.unlock();
     *                 }
     *            </pre>
     * @return read lock corresponding to key
     * @see org.paraj.sync.ResourceMonitor#writerEnters
     */
    Lock readerEnters(Object key);
}
